Flutter使用json

您所在的位置:网站首页 android 泛型code msg data Flutter使用json

Flutter使用json

2024-07-16 21:05| 来源: 网络整理| 查看: 265

前言

我是使用json_serializable这个插件进行json序列化的。

因为服务器返回的json结构都是统一如下结构:

{ "code": 200, "message": "SUCCESS", "data": { "countdown": 3, "createDate": 1625647940000, "modifiedDate": 1625647940000 } }

自然就会想通过一个泛型的方式,进行封装,进而不用每个json序列化model都包含code、message的通用部分。

当我直接把data通过泛型抽取出来时,执行如下命令生成代码时,出现如下错误:

import 'package:json_annotation/json_annotation.dart'; part 'response_model.g.dart'; @JsonSerializable(explicitToJson: true) class ResponseModel { T? data; int? code; String? message; ResponseModel({ this.data, this.code, this.message }); factory ResponseModel.fromJson(Map json) => _$ResponseModelFromJson(json); Map toJson() => _$ResponseModelToJson(this); }

错误:

flutter packages pub run build_runner build [INFO] Generating build script... [INFO] Generating build script completed, took 515ms [INFO] Initializing inputs [INFO] Reading cached asset graph... [INFO] Reading cached asset graph completed, took 61ms [INFO] Checking for updates since last build... [INFO] Checking for updates since last build completed, took 511ms [INFO] Running build... [INFO] 1.3s elapsed, 10/14 actions completed. [SEVERE] json_serializable:json_serializable on lib/model/response_model.dart: Could not generate `fromJson` code for `data` because of type `T` (type parameter). To support type parameters (generic types) you can: * Use `JsonConverter` https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html * Use `JsonKey` fields `fromJson` and `toJson` https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html * Set `JsonSerializable.genericArgumentFactories` to `true` https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/genericArgumentFactories.html package:doucan_flutter/model/response_model.dart:6:6 ╷ 6 │ T? data; │ ^^^^ ╵ [INFO] Running build completed, took 1.6s [INFO] Caching finalized dependency graph... [INFO] Caching finalized dependency graph completed, took 61ms [SEVERE] Failed after 1.6s pub finished with exit code 1

主要问题就是这里: Could not generate `fromJson` code for `data` because of type `T` (type parameter).

在GitHub的issue中找到如下答案: https://github.com/google/json_serializable.dart/issues/252 在这里插入图片描述 依葫芦画瓢改了一下,木有成功,可能我理解不到位。

于是继续Google…

发现了这篇文章: https://wamae.medium.com/generics-and-json-serialization-in-flutter-a8d335840d7b

按照里面的写法成功了一大半,但还是有些错误,可能和flutter版本有关,我使用的是Flutter 2.2.3 Dart 2.13.4。

做些调整后就成功了!!~

因为具体Data类的fromJson接收的参数类型为Map json,而原文中的是Object,导致调用时失败。以下为修改内容:

//原文: factory BaseResponse.fromJson( Map json, T Function(Object json) fromJsonT, ) => _$BaseResponseFromJson(json, fromJsonT); // 改为: factory BaseResponse.fromJson( Map json, T Function(Map json) fromJsonT ) => _$BaseResponseFromJson(json, fromJsonT); //相对应的,base_response.g.dart文件也需要修改FromJson方法中的参数变量类型

以下是最终的代码:

## file : response_model.dart import 'package:json_annotation/json_annotation.dart'; part 'response_model.g.dart'; @JsonSerializable( genericArgumentFactories: true, fieldRename: FieldRename.snake) class ResponseModel { @JsonKey(name: 'code') final int code; @JsonKey(name: 'message') final String message; @JsonKey(name: 'data') final T data; ResponseModel(this.data, this.code, this.message); factory ResponseModel.fromJson( Map json, T Function(Map json) fromJsonT) => _$ResponseModelFromJson(json, fromJsonT); Map toJson(Object Function(T value) toJsonT) => _$ResponseModelToJson(this, toJsonT); } ## file : response_model.g.dart // GENERATED CODE - DO NOT MODIFY BY HAND part of 'response_model.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** ResponseModel _$ResponseModelFromJson( Map json, T Function(Map json) fromJsonT, ) { return ResponseModel( fromJsonT(json['data']), json['code'] as int, json['message'] as String, ); } Map _$ResponseModelToJson( ResponseModel instance, Object? Function(T value) toJsonT, ) => { 'code': instance.code, 'message': instance.message, 'data': toJsonT(instance.data), };

开始食用:

data具体类:

import 'package:json_annotation/json_annotation.dart'; part 'splash_model.g.dart'; @JsonSerializable(explicitToJson: true) class SplashmodelData { int countdown; int createDate; int modifiedDate; SplashmodelData( this.countdown, this.createDate, this.modifiedDate, ); factory SplashmodelData.fromJson(Map json) => _$SplashmodelDataFromJson(json); Map toJson() => _$SplashmodelDataToJson(this); } import 'dart:convert'; import 'package:doucan_flutter/config/network_config.dart'; import 'package:doucan_flutter/model/response_model.dart'; import 'package:doucan_flutter/model/splash_model.dart'; import 'package:http/http.dart' as http; class SplashDao { static Future fetch() async { Uri url = Uri.parse(NetworkConfig.url('app_launcher/patient/splash')); final respones = await http.get(url); print(respones.statusCode); print(respones.body); if (respones.statusCode == 200) { var jsonResult = json.decode(Utf8Decoder().convert(respones.bodyBytes)); return ResponseModel.fromJson( jsonResult, (data) => SplashmodelData.fromJson(data)).data; } else { throw Exception( 'request app_launcher/patient/splash failed '); } } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3